package com.k7.mobile.platform.bo.impl;

import java.io.Serializable;

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import com.k7.mobile.platform.bo.IJedisBO;
import com.k7.mobile.platform.exception.BOException;
import com.k7.mobile.platform.util.ObjectUtil;

public class JedisBOImpl extends BaseBOImpl implements IJedisBO{
	private int maxActive;
	private int maxIdle;
	private int maxWait;
	private boolean testOnBorrow;
	private boolean testOnReturn;
	private String ip;
	private int port;
	private int dbIndex;
	private boolean enableCache;
	
	private static JedisPool pool;
	
	@Override
	public void init(){
		JedisPoolConfig config = new JedisPoolConfig();
		config.setMaxActive(maxActive);
		config.setMaxIdle(maxIdle);
		config.setMaxWait(maxWait);
		config.setTestOnBorrow(testOnBorrow);
		config.setTestOnReturn(testOnReturn);
		pool = new JedisPool(config, ip, port);
	}
	
	@Override
	public void set(String key, Serializable value){
		Jedis jedis = pool.getResource();
		jedis.select(dbIndex);
		try{
			jedis.set(key.getBytes(), ObjectUtil.objectToBytes(value));
		}catch(Exception e){
			log.error("JedisBOImpl:set,存储对象到redis失败.", e);
			throw new BOException("存储对象到redis失败.", e);
		}finally{
			pool.returnResource(jedis);
		}
	}
	
	@Override
	public void set(String key, Serializable value, int expiredTime){
		Jedis jedis = pool.getResource();
		jedis.select(dbIndex);
		try{
			jedis.setex(key.getBytes(), expiredTime, ObjectUtil.objectToBytes(value));
		}catch(Exception e){
			log.error("JedisBOImpl:set,存储对象到redis失败.", e);
			throw new BOException("存储对象到redis失败.", e);
		}finally{
			pool.returnResource(jedis);
		}
	}
	
	@Override
	public <T> T get(String key){
		if(!enableCache)
			return null;
		Jedis jedis = pool.getResource();
		jedis.select(dbIndex);
		try{
			byte[] b = jedis.get(key.getBytes());
			if(b == null || b.length == 0)
				return null;
			return ObjectUtil.bytesToObject(b);
		}catch(Exception e){
			log.error("JedisBOImpl:set,从redis获取对象失败.", e);
			throw new BOException("从redis获取对象失败.", e);
		}finally{
			pool.returnResource(jedis);
		}
	}
	
	@Override
	public boolean delete(String key){
		Jedis jedis = pool.getResource();
		jedis.select(dbIndex);
		try{
			Long count = jedis.del(key.getBytes());
			if(count >= 1)
				return true;
			else
				return false;
		}catch(Exception e){
			log.error("JedisBOImpl:set,redis计数失败.", e);
			throw new BOException("redis计数失败.", e);
		}finally{
			pool.returnResource(jedis);
		}
	}
	
	@Override
	public Long incr(String key){
		Jedis jedis = pool.getResource();
		jedis.select(dbIndex);
		try{
			return jedis.incr(key);
		}catch(Exception e){
			log.error("JedisBOImpl:incr,redis计数失败.", e);
			throw new BOException("redis计数失败.", e);
		}finally{
			pool.returnResource(jedis);
		}
	}
	
	@Override
	public Long getCounter(String key){
		Jedis jedis = pool.getResource();
		jedis.select(dbIndex);
		try{
			String count = jedis.get(key);
			if(count == null)
				return null;
			return Long.parseLong(count);
		}catch(Exception e){
			log.error("JedisBOImpl:get,redis计数失败.", e);
			throw new BOException("redis计数失败.", e);
		}finally{
			pool.returnResource(jedis);
		}
	}
	
	@Override
	public void setCounter(String key, Long counter){
		Jedis jedis = pool.getResource();
		jedis.select(dbIndex);
		try{
			jedis.set(key, counter.toString());
		}catch(Exception e){
			log.error("JedisBOImpl:set,redis计数失败.", e);
			throw new BOException("redis计数失败.", e);
		}finally{
			pool.returnResource(jedis);
		}
	}

	public void setMaxActive(int maxActive) {
		this.maxActive = maxActive;
	}

	public void setMaxIdle(int maxIdle) {
		this.maxIdle = maxIdle;
	}

	public void setMaxWait(int maxWait) {
		this.maxWait = maxWait;
	}

	public void setTestOnBorrow(boolean testOnBorrow) {
		this.testOnBorrow = testOnBorrow;
	}

	public void setTestOnReturn(boolean testOnReturn) {
		this.testOnReturn = testOnReturn;
	}

	public void setIp(String ip) {
		this.ip = ip;
	}

	public void setPort(int port) {
		this.port = port;
	}

	public int getDbIndex() {
		return dbIndex;
	}

	public void setDbIndex(int dbIndex) {
		this.dbIndex = dbIndex;
	}

	public void setEnableCache(boolean enableCache) {
		this.enableCache = enableCache;
	}

	
	
}
